\documentclass[twoside,a4paper]{ctexart}
\usepackage{geometry}
\geometry{margin=1.5cm, vmargin={0pt,1cm}}
\setlength{\topmargin}{-1cm}
\setlength{\paperheight}{29.7cm}
\setlength{\textheight}{25.3cm}

% useful packages.
\usepackage{amsfonts}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{amsthm}
\usepackage{enumerate}
\usepackage{graphicx}
\usepackage{multicol}
\usepackage{fancyhdr}
\usepackage{layout}
\usepackage{subfigure}

% some common command
\newcommand{\dif}{\mathrm{d}}
\newcommand{\avg}[1]{\left\langle #1 \right\rangle}
\newcommand{\difFrac}[2]{\frac{\dif #1}{\dif #2}}
\newcommand{\pdfFrac}[2]{\frac{\partial #1}{\partial #2}}
\newcommand{\OFL}{\mathrm{OFL}}
\newcommand{\UFL}{\mathrm{UFL}}
\newcommand{\fl}{\mathrm{fl}}
\newcommand{\op}{\odot}
\newcommand{\Eabs}{E_{\mathrm{abs}}}
\newcommand{\Erel}{E_{\mathrm{rel}}}

\begin{document}

\pagestyle{fancy}
\fancyhead{}
\lhead{邵柯欣 (3200103310)}
\chead{Numerical PDE project 1}
\rhead{\today}


\section*{I. 文件介绍}
整个作业文件由三个子文件夹（src,doc,fig）构成，分别用来存放代码，报告，图片．所有文件通过Ｍakefile管理．只需在Ｍakefile所在目录下输入make，即可生成测试代码的可执行文件；在改目录下输入clean，就能删除make生成的文件，回到初始状态． 

\subsection*{I-ａ求解器代码结构介绍} 
求解器构造在Solve.h文件里，核心是求解AU = F问题．

头文件里定义了几个结构和类，用来实现功能和存储相应的变量．

Point结构用来模拟二维点的结构，有结构变量ｘｙ，表示两个坐标．

Cricle类用来实现圆，输入原点和半径确定一个圆．子函数InOnCricle(Point p)，用以判断点ｐ是否在圆内；子函数Caculate\_X(double y) 和　Caculate\_Y(double x)，用以在确定一个坐标的情况下计算圆上的另一个坐标，通常会得到两个值，所以用大小为２的容器储存结果．

Value 类用来存储原函数导函数的信息，子函数输入一个点返回该点的函数值，后面出现需要求值的情况可以直接调用 Value 类的子函数．

Grid 类用来存储一连串网格点的信息，Ｇ为所有网格点的坐标，IG为需要求解的网格点信息（例如狄力克雷边界条件下IG为Ｇ除去边界的点），Label负责给所有网格点标记，与Ｇ大小相等且一一对应，当点在圆内或圆上打上标签-1，当点在边界上时标记为０，否则将点添加到IG中标记为ｊ(j　为该点在IG中的坐标加１)．

Solver 类，输入变量为Ｎ（分割细度）,TYPE（边界条件类型，＂Ｄ＂代表狄力克雷，＂Ｎ＂代表诺曼）,X（圆心的ｘ坐标）,Y（圆心的ｙ坐标）,R（圆心的半径），根据输入的分割Ｎ和圆的信息去调用上述类和函数接口生成Ａ和Ｆ，然后使用Lapack包求解Ｕ即为计算结果，ERROR 函数用来计算并输出误差的１范数，２范数，无穷范数．

需要解释的是：

求解器的输入变量没有用来区分定义域是否挖去圆形的变量，是因为不挖去圆形区域可以看成圆心在零点且半径为零．
求解器的输入除了上述的模式，也可以只输入N,TYPE，此时默认圆心在零点且半径为零．
\subsection*{I-ｂ对不合法输入的检测排除}
首先检测TYPE，当其输入值不为＂Ｄ＂或＂Ｎ＂时，输出错误，退出程序；
其次检测圆，当圆不能包含大于等于４个点或圆超出［０，１］＊［０，１］的区域时，输出错误，退出程序．

\section*{II. Ａ，Ｆ生成过程}
如上一部分中所述，需要求解的点被存储在向量容器IG中，因此Ａ和Ｆ的大小与容器一致即可．
Ａ的所有初值设为０，Ｆ的所有初值设为负的求解点的二阶导函数值．
对Ａ和Ｆ的修正根据公式
\begin{equation}
  L_hU_P := \dfrac{(1 + \theta)U_P - U_A - \theta U_W}{\dfrac{1}{2}\theta (1 + \theta) h^2} + \dfrac{(1 + \alpha)U_P - U_B - \alpha U_S}{\dfrac{1}{2}\alpha (1 + \alpha) h^2}.
\end{equation}

不需要对远离圆形区域或定义域没有挖去圆形区域的点另外使用公式$f_{ij} := -\dfrac{U_{i-1,j} - 2U_{ij} + U_{i+1,j}}{h^2} - \dfrac{U_{i,j-1} - 2U_{ij} + U_{i,j+1}}{h^2}$，因为这些情形可以看成$\alpha,\theta$都为１的情况．

实现时我选择历遍$IG$中的点，对每一个点定位其在Ｇ中的位置，依次探索其上下左右四个点，若探索到的点在边界上，则根据公式对右端项Ｆ进行修改，若探索到的点在圆内，则计算圆上的边界值，并根据公式对右端项进行修改；若探索到的点也为需要求解的点，则可通过标记的数字大小知道两点在中的相对位置，并根据公式对Ａ的对应位置进行修改．

\section*{III. 测试样例与测试结果展示}
计算结果:
\begin{figure}[htbp]
	\centering
	\subfigure[N = 8] {\includegraphics[width=.3\textwidth]{../fig/8.png}}
	\subfigure[N = 16] {\includegraphics[width=.3\textwidth]{../fig/16.png}}
	\subfigure[N = 32] {\includegraphics[width=.3\textwidth]{../fig/32.png}}
        \subfigure[N = 64] {\includegraphics[width=.3\textwidth]{../fig/64.png}}
	\caption{规则定义域下狄力克雷边界条件}
	\label{fig_E1}
\end{figure}
\begin{figure}[htbp]
	\centering
	\subfigure[N = 8] {\includegraphics[width=.3\textwidth]{../fig/i8.png}}
	\subfigure[N = 16] {\includegraphics[width=.3\textwidth]{../fig/i16.png}}
	\subfigure[N = 32] {\includegraphics[width=.3\textwidth]{../fig/i32.png}}
        \subfigure[N = 64] {\includegraphics[width=.3\textwidth]{../fig/i64.png}}
	\caption{不规则定义域下狄力克雷边界条件}
	\label{fig_E２}
\end{figure}

\begin{figure}[htbp]
	\centering
	\subfigure[规则定义域下狄力克雷边界条件] {\includegraphics[width=.4\textwidth]{../fig/u11.png}}
	\subfigure[不规则定义域下狄力克雷边界条件] {\includegraphics[width=.4\textwidth]{../fig/u22.png}}
	\caption{误差结果}
	\label{fig_E３}
\end{figure}
误差收敛结果

\section*{IV. 心得感悟}
我的代码只是很单一的实现了狄力克雷边值条件下的微分方程求解，对于诺曼边值条件以及混合编制条件都没有实现．
两周前开始着手项目作业时，自我感觉良好，对每一种条件都有一些想法，但是真正开始搭建求解器的框架时，才发现事情比我原本想象的还要难很多．把书上例子定理转化成现实的代码需要对每一个函数和变量的产生消亡作用都烂熟于心，不然很容易造成冗余，前面已经定义过差不多的变量后面又定义了一个．特别的，这次我对注释的重要性有了更深刻的体会，经常第二天甚至写着写着就会忘记自己前面写了啥，这让我花费了很多时间去一遍一遍的重新推演．抱着能实现一种情况是一种的心情，我先写了规则定义域狄力克雷边界条件下的求解器实现，断断续续花了有一大半的时间才能勉强出来个结果（C++不精通，debug　真的能把我整疯），然后又反复推敲验证才把结果整对．接下来，开始实现不规则定义域狄力克雷条件，后面发现规则狄力克雷可以看成不规则狄力克雷的特殊情况，就突然有一种我前面写了几百行垃圾的感觉．这里非常感谢欧阳杰学长，在我死磕诺曼条件而没有头绪的时候让我先试试不规则狄力克雷，以及我的求解方法也是在和欧阳杰学长讨论的时候想到的．
让我很困惑的一点就是我结果的误差，不管是三个范数中的哪一个，当ｎ不断增大时变化几乎没有，简而言之，误差是Ｏ（１）的．我实在想不到为什么会这样．［＞＿＜］
\end{document}
